<?php

namespace App\Http\Controllers;

use App\Http\Models\Item;
use App\Http\Models\Record;
use App\Http\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Http\Models\Task;
use App\Http\Models\Rank;
use App\Http\Models\RedPacket;

class UserController extends Controller
{

    public function __construct()
    {
        //
    }

    public function heartBeat(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        Redis::set('LyfenHeartbeat:'.$uid, self::now());

        return $this->result();
    }

    public function duckInfo(Request $req)
    {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId']) || $uinfo['duckId'] < 1) {
            return $this->error('鸭子信息获取失败');
        }

        $duck_id = $uinfo['duckId'];
        $duck_info = DB::table('ducks')->where('id', $duck_id)->first();
        if(!isset($duck_info['id'])) return $this->error('鸭子信息获取失败');

        // 判断剩余饲料
        $now_sec = time();
        $now = self::now();

        // 刷新剩余饲料 计算别人来偷吃饲料 计算星星获得
        User::refreshFodder($uid, $duck_info, false);

        $my_steal = null;
        if($duck_info['status'] == config('game.cfg.DuckStatus.Steal')) {
            // 计算自己出门偷吃收益
            $my_steal = DB::table('droparounds')->where('id', $uid)->first();
            if($my_steal['friendUserId'] > 0) {
                $null = null;
                $steal_fodder = User::refreshFodder($my_steal['friendUserId'], $null, true);
                if($steal_fodder > 0) {
                    $duck_info['feedCount'] += $steal_fodder;
                }
            }
        } else {
            // 还剩饲料 吃饭中
            if ($duck_info['leftFodder'] > 0) {
                $duck_info['status'] = config('game.cfg.DuckStatus.None');
            } // 没饲料了 饥饿中
            else {
                // 算算能否出门
                // 今天注册的不出走
                if(date('Y-m-d', $uinfo['createTime']) != date('Y-m-d')) {
                    $drop_around = DB::table('droparounds')->where('id', $uid)->first();
                    if (!isset($drop_around['id']) || $drop_around['friendUserId'] == 0) {
                        // 检查是否出门冷却中
                        if ($duck_info['backTime'] + config('game.cfg.BaseGooutColdTime') > $now) { //================================
                            // 偷吃冷却中
                            $duck_info['status'] = config('game.cfg.DuckStatus.None');
                            $duck_info['startTime'] = 0;
                        } else {
                            // 上次检查偷吃的时间 30分钟冷却
                            $last_check_steal = $duck_info['lastCheckSteal'] ?? 0;
                            if ($now - $last_check_steal > 1800000) { //================================
                                // 概率触发偷吃
                                $seed = mt_rand(0, 100);
                                if ($seed < config('game.cfg.BaseDropAroundRate')) { //================================
                                    // 寻找合适的好友
                                    $my_friends = User::myFriends($uid);
                                    $valid_friend_ids = []; // 符合条件的好友id
                                    if (!empty($my_friends)) {
                                        foreach ($my_friends as $mf) {
                                            if ($mf['duckId'] < 1) continue;
                                            $f_duck = DB::table('ducks')->where('id', $mf['duckId'])->first();
                                            if (!isset($f_duck['id'])) continue;
                                            $fuinfo = DB::table('users')->where('id', $mf['uid'])->first();
                                            if($fuinfo['level'] < 1) continue;

                                            User::refreshFodder($mf['uid'], $f_duck, false);
                                            // TODO 计算对方鸭子剩余饲料
                                            if ($f_duck['leftFodder'] > 50) {
                                                $find_steal = DB::table('droparounds')->where('friendUserId', $mf['uid'])->first();
                                                if(isset($find_steal['id'])) continue;  // 有人来偷吃了 跳过
                                                $valid_friend_ids[] = $mf['uid']; //================================
                                            }
                                            if (count($valid_friend_ids) > 10) break;    // 有10个合格的好友就住手吧，够了
                                        }
                                    }
                                    if (!empty($valid_friend_ids)) {
                                        $bad_luck_seed = array_rand($valid_friend_ids);
                                        $choose_friend_id = $valid_friend_ids[$bad_luck_seed];
                                        // 出门咯
                                        $duck_info['startTime'] = $now;
                                        $duck_info['status'] = config('game.cfg.DuckStatus.Steal');
                                        // 增加出门记录
                                        DB::statement("REPLACE INTO droparounds values ('" . $uid . "', '" . $choose_friend_id . "', " . $duck_info['id'] . ", $now_sec, $now_sec, 0, 0)");
                                        // 记录出门事件
                                        Record::new($uid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordDropAround'), []);
                                        $my_steal = ['friendUserId' => $choose_friend_id];
                                    }
                                    // 更新检查偷吃时间， 防止过量搜索好友列表
                                    $duck_info['lastCheckSteal'] = $now;
                                }
                            }
                        }
                    }
                }
            }
        }

        // 不开心状态判断
        if($duck_info['status'] != config('game.cfg.DuckStatus.Steal') && $duck_info['leftFodder'] < 1) {
            $offline = Redis::GET('LyfenHeartbeat:' . $uid);
            if ($offline > 0) {
                if ($now - $offline > config('game.cfg.OfflineTimeMax')) {
                    $duck_info['status'] = config('game.cfg.DuckStatus.Angry');
                }
            }
        }

        // 判断套装是否过期
        $expire = 0;
        if($duck_info['dressupId'] != 0) {
            $dress_confs = config('dressup.cfg');
            if(isset($dress_confs[$duck_info['dressupId']])) {
                $dress_info = DB::table('dressups')->where(['userId'=>$uid, 'confId'=>$duck_info['dressupId']])->first();
                if(isset($dress_info['id'])) {
                    if( time() >= ($dress_info['lastGetTime'] + $dress_info['durationTime']) ) {
                        $duck_info['dressupId'] = 0;
                        $expire = 0;
                    } else {
                        $expire = ($dress_info['lastGetTime'] + $dress_info['durationTime']);
                    }
                }
            }
        }

        DB::table('ducks')->where('id', $duck_info['id'])->update([
            'dressupId' => $duck_info['dressupId'],
            'status' => $duck_info['status'],
            'startTime' => $duck_info['startTime'],
            'lastCheckSteal' => $duck_info['lastCheckSteal'],
            'backTime' => $duck_info['backTime'],
            // 更新狗粮
            'leftFodder' => $duck_info['leftFodder'],
            'updateFeedTime' => $duck_info['updateFeedTime'],
            'feedCount' => $duck_info['feedCount'],
            'waitGainStar' => $duck_info['waitGainStar'],
        ]);

        return $this->result([
            'duck'        => $duck_info,                                    // 自己鸭子信息
            'skinSumDate' => $expire,                                       // 套装过期时间
            'dropAround'  => User::getDropRound($uid),                      // 别人家鸭子来偷吃的信息
            'stealUid'    => $my_steal ? $my_steal['friendUserId'] : null,  // 自己鸭子去好友家偷吃，好友的uid
        ]);
    }

    public function feedDuck(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $duck_id = $uinfo['duckId'];
        $duck_info = DB::table('ducks')->where('id', $duck_id)->first();
        if(!isset($duck_info['id'])) return $this->throwError('ErrGetDuck');

        // 判断饲料
        $need_fodder = config('game.cfg.BasePerFeedConsume');
        if($uinfo['fodder'] < $need_fodder) {
            // return $this->error('饲料不足', '10043');
            return $this->throwError('ErrNotEnoughFodder');
        }
        // 刷新剩余饲料 计算别人来偷吃饲料 计算星星获得
        User::refreshFodder($uid, $duck_info, false);

        $now = time();
        // 特殊逻辑 处理鸭子第一次喂食,5s结束
        if($duck_info['feedCount'] <= 0 && !$duck_info['updateFeedTime']) {
            $duck_info['startFeedTime'] = $duck_info['updateFeedTime'] = $now;
            $need_fodder = config('game.cfg.BasePerFeedConsume');
            $duck_info['leftFodder'] = 40;
            $duck_info['feedCount'] = config('game.cfg.BasePerFeedConsume')-40;
            $lastFeedTime = config('game.cfg.NewbieFeedIntervalTime');
            // $duck_info['waitGainStar'] = config('game.cfg.BasePerLvupStarNum') - 1;
        }else{
            // 没吃完喂个毛
            if($duck_info['leftFodder'] > 0) return $this->throwError('ErrFeedColdTime');
            if($duck_info['leftFodder'] < 0) $duck_info['leftFodder'] = 0;

            $duck_info['leftFodder'] = config('game.cfg.BasePerFeedConsume');

            $duck_info['startFeedTime'] = $now;
            $duck_info['updateFeedTime'] = $now;
            $lastFeedTime = config('game.cfg.BasePerDigestionTime');
        }

        DB::beginTransaction();
        try {
            DB::table('users')->where('id', $uid)->decrement('fodder', $need_fodder);
            DB::table('ducks')->where('id', $duck_id)->update([
                'feedCount' => $duck_info['feedCount'],
                'leftFodder' => $duck_info['leftFodder'],
                'startFeedTime' => $duck_info['startFeedTime'],
                'updateFeedTime' => $duck_info['updateFeedTime'],
                'waitGainStar' => $duck_info['waitGainStar'],
                'lastFeedTime' => $lastFeedTime,
            ]);
            $newLevel = User::levelUp( $uid );

        } catch(\Exception $e) {
            DB::rollBack();
            return $this->throwError('ErrFeedDbOperate', $e->getMessage());
        }
        DB::commit();

        $duck_info['lastFeedTime'] = $lastFeedTime;

        // 喂食任务
        Task::setProgress($uid, config('game.cfg.TaskIdFeed'), 1);

        // 增加一条喂食记录
        Record::new($uid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordFeed'), [$need_fodder]);

        RedPacket::set($uid, 1);

        file_put_contents('/tmp/fodder_change.log', date('Y-m-d').' ===== '.'  uid:'.$uid.' from:feed_duck  change:-'.$need_fodder.'  before:'.$uinfo['fodder'].'  after:'.($uinfo['fodder']-$need_fodder)."\n", FILE_APPEND);
        #file_put_contents('/tmp/fodder.log', date('Y-m-d H:i:s')."=========================\n".$uid."\n"."sub fodder: $need_fodder\n"."left fodder: ".($uinfo['fodder']-$need_fodder)."\n\n", FILE_APPEND);

        // 有等级变更时, 发放奖励
        $add_rewards = [];
        $next_reward = 0;
        $isLevelUp = false;
        if($uinfo['level'] != $newLevel['level']) {
            $level_reward = Task::getLevelReward($newLevel['level']);
            if($level_reward['cond'] == $newLevel['level']) {
                $add_rewards = Item::give($uid, $level_reward['reward'], $uinfo, 'gain_star_level');
            } else {
                $next_reward = $level_reward['cond'] - $newLevel['level'];
            }
            $isLevelUp = true;
            file_put_contents('/tmp/levelUp_reward.log', "userId: $uid time: ".date('Y-m-d H:i:s', time()).
                " newLevel: {$newLevel['level']}, oldLevel: {$uinfo['level']} reward: ".json_encode($add_rewards)."\n", FILE_APPEND);
        }

        return $this->result([
            'duck' => $duck_info,
            'fodder' => $uinfo['fodder']-$need_fodder,
            'rewards' => $add_rewards,
            'nextRewardLevel' => $next_reward,
            'isLevelUp' => $isLevelUp,
            'level' => $newLevel['level'],
            'exp' => $newLevel['exp'],
        ]);
    }

    public function gainStar(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $duck_id = $uinfo['duckId'];
        $duck_info = DB::table('ducks')->where('id', $duck_id)->first();
        if(!isset($duck_info['id'])) return $this->throwError('ErrGetDuck');

        // 刷新剩余饲料 计算别人来偷吃饲料 计算星星获得
        User::refreshFodder($uid, $duck_info, true);

        if($duck_info['waitGainStar'] <= 0) {
            return $this->throwError('ErrHasNoStar');
        }

        // 收货星星 触发升级
        DB::table('ducks')->where('id', $duck_id)->update(['waitGainStar'=>0]);

        // $old_level = $uinfo['level'];
        // 加道具
        Item::give($uid, [['id'=>0, 'type'=>6, 'num'=>$duck_info['waitGainStar']]], $uinfo, 'gain_star');

        // 有等级变更时, 发放奖励
        // $add_rewards = [];
        // $next_reward = 0;
        // $isLevelUp = false;
        // if($uinfo['level'] != $old_level) {
        //     $level_reward = Task::getLevelReward($uinfo['level']);
        //     if($level_reward['cond'] == $uinfo['level']) {
        //         $add_rewards = Item::give($uid, $level_reward['reward'], $uinfo, 'gain_star_level');
        //     } else {
        //         $next_reward = $level_reward['cond'] - $uinfo['level'];
        //     }
        //     $isLevelUp = true;
        //     file_put_contents('/tmp/levelUp_reward.log', "userId: $uid time: ".date('Y-m-d H:i:s', time()).
        //         " oldLevel: $old_level, newLevel: {$uinfo['level']} reward: ".json_encode($add_rewards)."\n", FILE_APPEND);
        // }

        // 增加一条记录
        Record::new($uid, config('game.cfg.BaseRecordTypeGain'), config('game.cfg.BaseRecordGainstar'), [$duck_info['waitGainStar']]);

        return $this->result([
            'waitGainStar' => 0,
            // 'level' => $uinfo['level'],
            // 'exp' => $uinfo['exp'],
            'star' => $uinfo['star'],
            'gainStar' => $duck_info['waitGainStar'],
            'feedCount' => $duck_info['feedCount'],
            // 'rewards' => $add_rewards,
            // 'nextRewardLevel' => $next_reward,
            // 'isLevelUp' => $isLevelUp,
        ]);
    }

    public function checkStar(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $duck_id = $uinfo['duckId'];
        $duck_info = DB::table('ducks')->where('id', $duck_id)->first();
        if(!isset($duck_info['id'])) return $this->throwError('ErrGetDuck');

        // 刷新剩余饲料 计算别人来偷吃饲料 计算星星获得
        User::refreshFodder($uid, $duck_info, true);

        return $this->result(['duck'=>$duck_info]);
    }

    public function dressupInfo(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['id'])) return $this->throwError('ErrGetUser');

        $dressup_conf = config('dressup.cfg');
        $dids = [];
        $dressup_list = [];
        foreach($dressup_conf as $dc) {
            $dids[] = $dc['id'];
            $dressup_list[$dc['id']] = [
                'id' => $dc['id'],
                'lastGetTime' => 0,
                'durationTime' => 0
            ];
        }
        $get_my_tasks = DB::table('user_task')->where('uid', $uid)->get();
        $my_dressups = DB::table('dressups')->where('userId', $uid)->whereIn('confId', $dids)->get();
        // 判断重置
        $now = time();
        $need_refre = [];
        if(!empty($my_dressups)) {
            foreach($my_dressups as $md) {
                // 套装过期, 需重置任务等
                if(($md['lastGetTime']+$md['durationTime']) <= $now) {
                    $need_refre[] = $md['confId'];
                }
            }
        }
        // 重置套装及任务
        if(!empty($need_refre)) {
            $tids_array = [];
            foreach($need_refre as $confId) {
                $tids_array = array_merge($tids_array, explode(',', $dressup_conf[$confId]['tid']));
            }
            // 重置任务
            DB::table('user_task')->where('uid', $uid)->whereIn('tid', $tids_array)->update([
                'status' => config('game.cfg.TaskStatusUncomplete'),
                'curr' => 0,
                'count' => 0,
                'finish' => 0,
            ]);
            // 重置套装
            DB::table('dressups')->where('userId', $uid)->whereIn('confId', $need_refre)->delete();
            // 修改鸭子身上的套装
            $duck_info = DB::table('ducks')->where('id', $uinfo['duckId'])->first();
            if(in_array($duck_info['dressupId'], $need_refre)) {
                DB::table('ducks')->where('id', $uinfo['duckId'])->update(['dressupId'=>0]);
            }
        }

        $get_all_task = Redis::HGETALL('TASK_DATA');
        $task_list = [];
        $dressup_task_ids = [];
        foreach($get_all_task as $at) {
            $t = json_decode($at, true);
            if($t['tt'] == 2) {
                $dressup_task_ids[] = $t['id'];
                $task_list[$t['id']] = [
                    'confId' => $t['id'],
                    'status' => config('game.cfg.TaskStatusUncomplete'),
                    'curr' => 0,
                    'dayGetNum' => 0,
                    'name' => $t['name'],
                    'desc' => $t['desc'],
                    'type' => $t['type'],
                    'iconUrl' => $t['iconUrl'],
                    'jump' => $t['jump'],
                    'target' => $t['target'],
                    'cond' => $t['cond'],
                    'button' => $t['btn_type'],
                ];
            }
        }

        $get_my_tasks = DB::table('user_task')->where('uid', $uid)->get();
        if(!empty($get_my_tasks)) {
            foreach($get_my_tasks as $mt) {
                if(!isset($task_list[$mt['tid']])) continue;
                $task_list[$mt['tid']]['status'] = $mt['status'];
                $task_list[$mt['tid']]['curr'] = $mt['curr'];
                $task_list[$mt['tid']]['dayGetNum'] = $mt['count'];
            }
        }

        $my_dressups = DB::table('dressups')->where('userId', $uid)->whereIn('confId', $dids)->get();
        if(!empty($my_dressups)) {
            foreach($my_dressups as $md) {
                if(!isset($dressup_list[$md['confId']])) continue;
                $dressup_list[$md['confId']]['lastGetTime'] = $md['lastGetTime'];
                $dressup_list[$md['confId']]['durationTime'] = $md['durationTime'];
            }
        }

        // 补充未进入套装
        $fill_dress = [];
        $finish_t = [];
        foreach($get_my_tasks as $mt) {
            if($mt['status'] == 2) $finish_t[$mt['tid']] = $mt['finish'];
        }
        foreach($dressup_conf as $dc) {
            $need_tid = explode(',', $dc['tid']);
            $has = true;
            $last = 0;
            foreach($need_tid as $nt) {
                if(!isset($finish_t[$nt])) {
                    $has = false;
                    break;
                }
                if($finish_t[$nt] > $last) $last = $finish_t[$nt];
            }
            if($has === true) {
                $fill_dress[$dc['id']] = $last;
            }
        }
        if(!empty($fill_dress)) {
            foreach($dressup_list as $k=>$d) {
                if(!isset($fill_dress[$d['id']])) continue;
                if($d['lastGetTime'] >= $fill_dress[$d['id']]) continue;
                DB::table('dressups')->insert([
                    'userId'=>$uid,
                    'confId'=>$d['id'],
                    'lastGetTime'=>$fill_dress[$d['id']],
                    'durationTime' => $dressup_conf[$d['id']]['duration']
                ]);
                $dressup_list[$k]['lastGetTime'] = $fill_dress[$d['id']];
                $dressup_list[$k]['durationTime'] = $dressup_conf[$d['id']]['duration'];
            }
        }

        $dlist = [];
        foreach($dressup_list as $d) {
            $d['lastGetTime'] += $d['durationTime'];
            unset($d['durationTime']);
            $dlist[] = $d;
        }

        return $this->result([
            'dressup' => $dlist,
            'task' => $task_list,
            'finish' => $finish_t,
            'fill_dress' => $fill_dress,
        ]);
    }

    public function dressup(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $dress_id = $req->input('id');
        if($dress_id < 0) $dress_id = 0;
        if($dress_id > 0) {
            $dressup_conf = config('dressup.cfg');
            if(!isset($dressup_conf[$dress_id])) return $this->throwError('ErrHasNoDressup');

            $get_dress = DB::table('dressups')->where(['userId'=>$uid, 'confId'=>$dress_id])->first();
            if(!isset($get_dress['id'])) return $this->throwError('ErrHasNoDressup');

            if(time() > ( $get_dress['lastGetTime'] + $get_dress['durationTime'])) {
                return $this->throwError('ErrHasNoDressup');
            }
        }

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        DB::table('ducks')->where('id', $uinfo['duckId'])->update(['dressupId'=>$dress_id]);

        return $this->result([]);
    }

    /**
     * 签到信息
     * @param Request $req
     * @return \Illuminate\Http\JsonResponse
     */
    public function signInfo(Request $req)
    {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $sign = DB::table('signs')->where('uid', $uid)->first();
        if(!isset($sign['uid'])) {
            $sign = ['uid'=>$uid, 'day'=>0, 'count'=>0];
            DB::table('signs')->insert($sign);
        }

        $today = date('Y-m-d');

        if($sign['day'] == $today) {
            $signed = 1;
            $curr = $sign['count'];
        } else {
            $signed = 0;
            $sign['count']++;
            if($sign['count'] > 7) $sign['count'] = 1;
            $curr = $sign['count'];
        }
        $rewards = $this->getSignData();
        if(!$sign['day']) {
            $rewards[0][0]['num'] = 1000;
        }

        return $this->result([
            'curr' => $curr,
            'signed' => $signed,
            'rewards' => $rewards,
        ]);
    }

    /**
     * 签到
     * @param Request $req
     * @return \Illuminate\Http\JsonResponse
     */
    public function signIn(Request $req)
    {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        //获取签到信息
        $sign = DB::table('signs')->where('uid', $uid)->first();
        if(!isset($sign['uid'])) {
            return $this->throwError('ErrSignData');
        }

        $today = date('Y-m-d');
        if($sign['day'] == $today) {
            $signed = 1;
            $curr = $sign['count'];
        } else {
            $signed = 0;
            $sign['count']++;
            if($sign['count'] > 7) $sign['count'] = 1;
            $curr = $sign['count'];
        }

        if ($signed == 1) return $this->throwError('ErrAlreadySignIn');
        if ($curr < 1 || $curr > 7) return $this->throwError('ErrSignIn');

        $signRewards = $this->getSignData();
        if(count($signRewards) != 7) return $this->throwError('ErrSignConf');
        // 新手的首次签到 奖励 增加
        if(!$sign['day']) {
            $signRewards[0][0]['num'] = 1000;
        }

        $uinfo = DB::table('users')->where('id', $uid)->first();
        // $max_fodder = min(config('game.cfg.BasePerProductStarFeedCount')+$uinfo['level']*200, config('game.cfg.BaseMaxStorageFodderNum'));

        $todayStr = $signRewards[$curr - 1];
        $add_fodder = 0;
        foreach($todayStr as $r) {
            if($r['type'] == 1) $add_fodder += $r['num'];
        }
        // if($uinfo['fodder'] + $add_fodder > $max_fodder) {
        //     return $this->throwError('ErrMaxFodder');
        // }

        $rewards = Item::give($uid, $todayStr, $uinfo, 'sign_day_'.($curr));
        // Task::setProgress($uid,config('game.cfg.TaskIDSignIn'),1);

        $sign['day'] = $today;
        DB::table('signs')->where('uid', $uid)->update([
            'day' => $sign['day'],
            'count' => $sign['count'],
        ]);

        // 完成任务
        $task_data = DB::table('user_task')->where(['uid'=>$uid, 'tid'=>config('game.cfg.TaskIDSignIn')])->first();
        if(!isset($task_data['uid'])) {
            $task_data = [
                'uid' => $uid,
                'tid' => config('game.cfg.TaskIDSignIn'),
                'status' => config('game.cfg.TaskStatusUncomplete'),
                'curr' => 0,
                'count' => 0,
                'finish' => 0,
            ];
            $new_tid = DB::table('user_task')->insert($task_data);
            if(!$new_tid) return $this->throwError('ErrCreateTask');
        }
        DB::table('user_task')->where(['uid'=>$uid, 'tid'=>config('game.cfg.TaskIDSignIn')])->update([
            'status'=>config('game.cfg.TaskStatusReceived'),
            'curr' => 1,
            'count' => 1,
            'finish' => time(),
        ]);

        // 活跃度排行榜
        $add_active = 0;
        // if(!empty($rewards['fodder'])) {
        //     $add_active = intval($rewards['fodder'] / 10);
        //     Rank::set( $uid, $add_active );
        // }

        if(!empty($add_fodder)) {
            $add_active = intval($add_fodder/ 10);
            Rank::set( $uid, $add_active );
        }
        // 检查任务红点
        Task::checkReddot( $uid );

        return $this->result([
            'rewards' => $rewards,
            'add_active' => $add_active,
        ]);
    }

    private function getSignData()
    {
        //$redis = \App\Common\Redis::getRedis();
        $signRewardStrs = Redis::hMGet('SIGN_DATA',[1,2,3,4,5,6,7]);
        if (!$signRewardStrs){
            return null;
        }
        $signRewards = [];
        foreach ($signRewardStrs as $v){
            $ret = json_decode($v,true);
            if ($ret){
                array_push($signRewards,$ret);
            }
        }
        return $signRewards;
    }

    public function recordInfo(Request $req) {
        $type = $req->input('type');
        $page = $req->input('page');
        if(!$type) return $this->throwError('ErrClientParams');
        if(!$page) $page = 1;
        if($page > 1) $records = [];
        else {

            $uid = \Auth::user();
            if (!$uid) return $this->throwError('ErrUnAuthorization');

            //        Record::new($uid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordDriveDuck'), ['test', 100, 13600000]);
            //        Record::new($uid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordRecallDuck'), ['test', 100, 13600000]);

            //        if($page < 1) $page = 1;
            //        $start = ($page - 1) * config('game.cfg.BaseRecordPerPage');
            //        $end = $start + config('game.cfg.BaseRecordPerPage');

            $records = Redis::LRANGE('LyfenUserRecord:' . $type . ':' . $uid, 0, 19);
            if (!$records) $records = [];
            // 特殊处理 防止出错
            if(!empty($records)) {
                foreach ($records as $key => $record) {
                    $record_arr = json_decode($record, true);
                    if($record_arr['type'] == config('game.cfg.BaseRecordProductEgg') && empty($record_arr['desc']) ) {
                        $record_arr['desc'] = [1];
                        $records[$key] = json_encode($record_arr);
                    }
                }
            }
        }

        $banner_list = [];
        $banners = Redis::HGETALL('BANNER_DATA');
        if(!empty($banners)) {
            foreach($banners as $banner) {
                $b_arr = json_decode($banner, true);
                $banner_list[] = [
                    'name' => $b_arr['name'],
                    'url' => $b_arr['url'],
                    'jump' => $b_arr['jump'],
                ];
            }
        }

        return $this->result([
            'list' => $records,
            'banners' => $banner_list,
        ]);
    }

    public function attention(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $attention = $req->input('attention');
        Redis::SET('LyfenUser:Attention:'.$uid, $attention);

        if($attention == 1) {
            $uinfo = DB::table('users')->where('id', $uid)->first();
            if(isset($uinfo['openid'])) {
                // 发送通知
                $url = 'https://api.laiyifen.com/im/sendMessage';
                $headers = ['Content-Type:application/json'];
                $params = json_encode([
                    "messageType" => "100",
                    "data" => [
                        "data" => [
                            "sysMessageTitle" => "关注成功",
                            "sysMessageInfo" => "欢迎来到鸭鸭的世界，快来开启你的养成之旅吧！",
                            "sysMessageDetaiUrl" => "",
                            "sysMessageOrderCode" => "",
                            "sysMessageImageUrl" => "",
                            "sysMessageOrigin" => "来养鸭"
                        ],
                        "type" => "9",
                    ],
                    "sessionId" => "lyfgamecenter",
                    "toSessionId" => $uinfo['openid'],
                    "sessionType" => "0"
                ]);
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                $output = curl_exec($ch);
                curl_close($ch);
            }
        }

        return $this->result([
            'msg' => $attention == 2 ? '关注成功，您将收到游戏相关推送' : '取消关注成功',
        ]);
    }

    public function getFollowStatus(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        // third.FollowStatus(u.OpenID)
    }

    public function recallDuck(Request $req) {
        $uid = \Auth::user();
        if(!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $duck_id = $uinfo['duckId'];
        $duck_info = DB::table('ducks')->where('id', $duck_id)->first();
        if(!isset($duck_info['id'])) return $this->throwError('ErrGetDuck');

        // 非出门状态无法召回
        if($duck_info['status'] != config('game.cfg.DuckStatus.Steal')) return $this->throwError('ErrRecallDuck');

        $find_steal = DB::table('droparounds')->where('id', $uid)->first();
        if(!isset($find_steal['id']) || $find_steal['friendUserId'] < 1) return $this->throwError('ErrRecallDuck');

        $finfo = DB::table('users')->where('id', $find_steal['friendUserId'])->first();
        if(!isset($finfo['nickName'])) $target_nickname = '玩家';
        else $target_nickname = $finfo['nickName'];

        $now = self::now();

        // 刷新剩余饲料 计算别人来偷吃饲料 计算星星获得
        $friend_duck = null;
        User::refreshFodder($find_steal['friendUserId'], $friend_duck, true);

        // 记录时间和总偷吃
        $spend_time = time() - $find_steal['stealTime'];
        //$total_steal = ceil($spend_time / 360);
        $find_steal = DB::table('droparounds')->where('id', $uid)->first();
        $total_steal = $find_steal['stealFodder'] < 1 ? 1 : $find_steal['stealFodder'];

        $duck_info['status'] = config('game.cfg.DuckStatus.None');
        $duck_info['backTime'] = self::now();

        DB::beginTransaction();
        DB::table('ducks')->where('id', $duck_id)->update([
            'status' => $duck_info['status'],
            'backTime' => $duck_info['backTime'],
            'lastCheckSteal' => 0,
        ]);
        DB::table('droparounds')->where('id', $uid)->update([
            'friendUserId' => 0,
            'stealTime' => 0,
            'updateTime' => 0,
            'stealFodder' => 0,
            'kickTime' => $now,
            'friendDuckId' => 0,
        ]);
        DB::commit();

        if($spend_time < 60) $spend_time = 60;

        // 增加一条记录
        // 你召回了你的小鸭，在XX的庄园待了XX小时，吃了XX饲料
        Record::new(
            $uid,
            config('game.cfg.BaseRecordTypeNormal'),
            config('game.cfg.BaseRecordRecallDuck'),
            [
                $target_nickname,
                $total_steal,
                $spend_time
            ]
        );
        // xx的小鸭，在你的庄园待了xx小时，吃了xx饲料被主人召回了
        Record::new(
            $find_steal['friendUserId'],
            config('game.cfg.BaseRecordTypeNormal'),
            config('game.cfg.BaseRecordFriendRecallDuck'),
            [
                $uinfo['nickName'],
                $total_steal,
                $spend_time
            ]
        );

        return $this->result([
            'duck' => $duck_info,
            'rewards' => null,
        ]);
    }

    public function driveDuck(Request $req) {
        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $duck_id = $uinfo['duckId'];
        $duck_info = DB::table('ducks')->where('id', $duck_id)->first();
        if(!isset($duck_info['id'])) return $this->throwError('ErrGetDuck');

        // 获取正在偷吃的鸭子
        $steal_duck = DB::table('droparounds')->where('friendUserId', $uid)->first();
        if(!isset($steal_duck['id'])) return $this->throwError('ErrNoStealDuck');

        $now = self::now();

        $finfo = DB::table('users')->where('id', $steal_duck['id'])->first();
        if(!isset($finfo['nickName'])) $target_nickname = '玩家';
        else $target_nickname = $finfo['nickName'];

        // 刷新剩余饲料 计算别人来偷吃饲料 计算星星获得
        User::refreshFodder($uid, $duck_info, true);

        // 记录时间和总偷吃
        $spend_time = time() - $steal_duck['stealTime'];
        //$total_steal = ceil($spend_time / 360);
        $find_steal = DB::table('droparounds')->where('friendUserId', $uid)->first();
        $total_steal = $find_steal['stealFodder'] < 1 ? 1 : $find_steal['stealFodder'];

        // 驱赶回家
        DB::beginTransaction();
        DB::table('droparounds')->where('friendUserId', $uid)->update([
            'friendUserId' => 0,
            'stealTime' => 0,
            'updateTime' => 0,
            'stealFodder' => 0,
            'kickTime' => $now,
            'friendDuckId' => 0,
        ]);
        // 修改对方鸭子的时间数据
        DB::table('ducks')->where('id', $steal_duck['friendDuckId'])->update([
            'startTime' => 0,
            'status' => 1,
            'backTime' => self::now(),
        ]);
        DB::commit();

        if($spend_time < 60) $spend_time = 60;
        // 增加一条记录
        // xx的小鸭，在你的庄园待了xx小时，吃了xx饲料被你赶走了
        Record::new($uid, config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordDriveDuck'), [$target_nickname, $total_steal, $spend_time]);
        // 你的小鸭在xxx的庄园待了xx小时xx分钟，吃了xxg饲料，被庄园主人赶回来了
        Record::new($steal_duck['id'], config('game.cfg.BaseRecordTypeNormal'), config('game.cfg.BaseRecordFriendDriveDuck'), [$uinfo['nickName'], $total_steal, $spend_time]);

        return $this->result([]);
    }

    /**
     * 各种标识
     *
     * @param Request $req
     * @return void
     */
    public function label(Request $req)
    {
        $uid = \Auth::user();
        if (!$uid) return $this->throwError('ErrUnAuthorization');

        $uinfo = DB::table('users')->where('id', $uid)->first();
        if(!isset($uinfo['duckId'])) return $this->throwError('ErrGetUser');

        $ret = ['sign' => false];
        $now = time();
        // 每日首次登陆弹出签到界面, 其他时候不弹
        $label_sign = Redis::HGET('Label:' . $uid, 'sign') ?? 0;
        if($now >= $label_sign) {
            $next_refre = strtotime(date('Y-m-d', $now)) + 86400;
            Redis::HSET('Label:' . $uid, 'sign', $next_refre);
            $ret['sign'] = true;
        }
        return $this->result($ret);
    }
}
